package com.zxy.ziems.collector.parse;

import com.zxy.ziems.common.pojo.enums.DataEnum;

import java.util.Arrays;
import java.util.Objects;

/**
 * 数据单元
 * @author 10348359
 * @create 2024-04-12
 */

public class Data {

    /**
     * 字段名
     */
    private String name;

    /**
     * 描述
     */
    private String description;

    /**
     * 单位
     */
    private String unit;

    /**
     * 字节数组
     */
    private byte[] bytes;

    /**
     * 具体的数值
     */
    private String value;

    /**
     * 字节偏移量，默认0
     */
    private int byteOffset = 0;

    /**
     * 位偏移量，默认0
     */
    private int bitOffset = 0;

    /**
     * 数据个数，默认1个，字节长度 = 数据个数 * 类型占的字节数
     * "bool": 1个字节,
     * "byte": 1个字节,
     * "ushort": 2个字节,
     * "short": 2个字节,
     * "int": 4个字节,
     * "uint": 4个字节,
     * "float": 4个字节,
     * "double": 8个字节,
     * "string": 1个字节
     */
    private int count = 1;

    /**
     * 字符串类型
     */
    private DataEnum dataType = DataEnum.STRING;

    /**
     * 是否为小端模式，默认false
     */
    private boolean littleEndian = false;

    public Data() {
    }

    public Data(int byteOffset, String dataType) {
        this.byteOffset = byteOffset;
        this.dataType = DataEnum.getBy(dataType);
    }

    public Data(int byteOffset, int count, String dataType) {
        this.byteOffset = byteOffset;
        this.count = count;
        this.dataType = DataEnum.getBy(dataType);
    }

    public Data(int byteOffset, int bitOffset, int count, String dataType, boolean littleEndian) {
        this.byteOffset = byteOffset;
        this.bitOffset = bitOffset;
        this.count = count;
        this.dataType = DataEnum.getBy(dataType);
        this.littleEndian = littleEndian;
    }

    public Data(int byteOffset, int bitOffset, int count, String dataType, String name) {
        this.byteOffset = byteOffset;
        this.bitOffset = bitOffset;
        this.count = count;
        this.dataType = DataEnum.getBy(dataType);
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        this.unit = unit;
    }

    public byte[] getBytes() {
        return bytes;
    }

    public void setBytes(byte[] bytes) {
        this.bytes = bytes;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public int getByteOffset() {
        return byteOffset;
    }

    public void setByteOffset(int byteOffset) {
        this.byteOffset = byteOffset;
    }

    public int getBitOffset() {
        return bitOffset;
    }

    public void setBitOffset(int bitOffset) {
        this.bitOffset = bitOffset;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public DataEnum getDataType() {
        return dataType;
    }

    public void setDataType(DataEnum dataType) {
        this.dataType = dataType;
    }

    public boolean getLittleEndian() {
        return littleEndian;
    }

    public void setLittleEndian(boolean littleEndian) {
        this.littleEndian = littleEndian;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Data)) return false;
        Data data = (Data) o;
        return getByteOffset() == data.getByteOffset() &&
                getBitOffset() == data.getBitOffset() &&
                getCount() == data.getCount() &&
                getLittleEndian() == data.getLittleEndian() &&
                Objects.equals(getName(), data.getName()) &&
                Objects.equals(getDescription(), data.getDescription()) &&
                Objects.equals(getUnit(), data.getUnit()) &&
                Arrays.equals(getBytes(), data.getBytes()) &&
                Objects.equals(getValue(), data.getValue()) &&
                getDataType() == data.getDataType();
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(getName(), getDescription(), getUnit(), getValue(), getByteOffset(), getBitOffset(), getCount(), getDataType(), getLittleEndian());
        result = 31 * result + Arrays.hashCode(getBytes());
        return result;
    }

    @Override
    public String toString() {
        return "DataUnit{" +
                "name='" + name + '\'' +
                ", description='" + description + '\'' +
                ", unit='" + unit + '\'' +
                ", bytes=" + Arrays.toString(bytes) +
                ", value=" + value +
                ", byteOffset=" + byteOffset +
                ", bitOffset=" + bitOffset +
                ", count=" + count +
                ", dataType='" + dataType + '\'' +
                ", littleEndian=" + littleEndian +
                '}';
    }
}
